/*
 * Copyright 2007 National Bioinformatics Network
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dgbgui.modeldocument;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import org.jgrapht.graph.DefaultDirectedGraph;

import dgbgui.modeldocument.primitives.Concept;
import dgbgui.modeldocument.primitives.Layer;
import dgbgui.modeldocument.primitives.RelationType;

public class DGBModel implements Serializable {
    


    public DGBModel(String name) {
        m_name = name;
        m_modelGraph = new DefaultDirectedGraph<Concept,ModelDrivenEdge>(ModelDrivenEdge.class);
    }
    
    public void addConcept(Concept c) {
        m_modelGraph.addVertex(c);
    }
    
    public void addEdge(Concept source, Concept target, RelationType relationType, Layer layer) {
        m_modelGraph.addEdge(source,target, new ModelDrivenEdge(relationType,layer));
    }
    
    public String getName() {
        return m_name;
    }
    
    
    public Set<Concept> getConcepts() {
        return m_modelGraph.vertexSet();
    }
    
    public Set<ModelDrivenEdge> getEdges() {
        return m_modelGraph.edgeSet();
    }
    
    public Set<Concept> getSourceConcepts(Concept concept) {
        Set<ModelDrivenEdge> edges = m_modelGraph.incomingEdgesOf(concept);
        Set<Concept> sources = new HashSet<Concept>();
        for ( ModelDrivenEdge edge : edges ) {
            sources.add(m_modelGraph.getEdgeSource(edge));
        }
        return sources;
    }
    
    public Set<Concept> getTargetConcepts(Concept concept) {
        Set<ModelDrivenEdge> edges = m_modelGraph.outgoingEdgesOf(concept);
        Set<Concept> sources = new HashSet<Concept>();
        for ( ModelDrivenEdge edge : edges ) {
            sources.add(m_modelGraph.getEdgeTarget(edge));
        }
        return sources;
    }
    
    /**
     * @param source
     * @param target
     * @return true if there is a dir3ected edge from source to target
     */
    public boolean hasEdge(Concept source, Concept target) {
        return(m_modelGraph.getAllEdges(source,target).size() == 1);
    }
    
    /**
     * @param source
     * @param target
     * @return The relation type that exists between these two vertices
     */
    public RelationType getRelationType(Concept source, Concept target) {
        assert(m_modelGraph.getAllEdges(source,target).size() == 1);
        return (m_modelGraph.getAllEdges(source,target).iterator().next().getRelationType());
    }
    

    /**
     * @param source
     * @param target
     * @return The layer instance that exists between these two vertices
     */
    public Layer getLayer(Concept source, Concept target) {
        assert(m_modelGraph.getAllEdges(source,target).size() == 1);
        return (m_modelGraph.getAllEdges(source,target).iterator().next().getLayerInstance());
    }
    
    public Concept getEdgeSource(ModelDrivenEdge edge) {
        return m_modelGraph.getEdgeSource(edge);
    }
    
    public Concept getEdgeTarget(ModelDrivenEdge edge) {
        return m_modelGraph.getEdgeTarget(edge);
    }
    
    /**
     * Default serial version
     */
    private static final long serialVersionUID = 1L;
    
    // ----- Fields -----
    
    private String m_name;
    private DefaultDirectedGraph<Concept,ModelDrivenEdge> m_modelGraph;



}
